import sys
sys.path.append(r'code')
from frame.training.ml_frame.month_rolling.quant import Quant
from data_read.get_feature import Get_feature_data_many,  Get_feature_data_select
from data_read.get_label import Get_label_data, Get_rank_label
import numpy as np
import argparse
import os 

#basic
parser = argparse.ArgumentParser(description='ml_training structure')
parser.add_argument('--result_root', type=str,  default='dl_test', help='the root to save result')
parser.add_argument('--feature_root', type=str,  default=None, help='the root to read feature')
parser.add_argument('--label_root', type=str,  default=None, help='the root to read label')
parser.add_argument('--model_name', type=str,  default='lightgbm',  help='model name, options: [lasso, lightgbm, liner, random_forest]')

#time
parser.add_argument('--time_param', type=dict,  default={"insample_beg": '2019-05',
                                                        "insample_end": '2021-7',
                                                        "outsample_beg": '2021-8',
                                                        "outsample_end": '2023-2',
                                                        }, help='time param for training')

#train_control
parser.add_argument('--rolling_step', type=int,  default=1, help='the step of rolling train')
parser.add_argument('--rolling_method', type=str,  default='cum', help='the method of rolling train')
parser.add_argument('--train_ratio', type=float,  default=0.8, help='the ratio to split train, eval and test')
parser.add_argument('--feature_list', type=list,  default=['high', 'low', 'close', 'vol', 'volume', 'oi'], help='feature name')
parser.add_argument('--varieties', type=list,  default=None, help='codes num')
parser.add_argument('--label_range', type=int,  default=5, help='the periods of thre sum of return')
parser.add_argument('--divide_vol', type=bool,  default=False, help='to decide that regression label is dividing vol')
parser.add_argument('--log_eval',  type=int,  default=50, help='the step of log_eval')
parser.add_argument('--predict_save', type=bool,  default=True, help='weather saving predict result')

parser.add_argument('--tune_param', type=bool,  default=False, help='weather saving predict result')

#model
parser.add_argument('--ml_param1', type=dict,  default={"task": "train", 
                                            "max_depth": 5, 
                                            "boosting_type": "goss", 
                                            "num_leaves": 28, 
                                            "n_estimators": 5000, 
                                            "objective": "regression", 
                                            "metric": 'rmse', 
                                            "learning_rate": 0.005, 
                                            "feature_fraction": 0.65, 
                                            "bagging_freq": 10, 
                                            "verbose": -1, 
                                            "n_jobs": 14}, help='model param')
parser.add_argument('--ml_param2', type=dict,  default={'num_boost_round': 500, 
                                                                'early_stopping_rounds': 200, 
                                                               'verbose_eval': 500}, help='model param verbose .etc')

# backtest
parser.add_argument('--backtest_time', type=dict,  default={"beg": '2021-9-28', "end": '2023-2-05', }, help='time param for backtest')
parser.add_argument('--cost_ratio', type=float,  default=0.001, help='the ratio of cost')
parser.add_argument('--money_init', type=float,  default=20000, help='the money of backtest')
parser.add_argument('--stop_loss', type=float,  default=-0.02, help='the ratio of stop loss')
parser.add_argument('--stop_ret', type=float,  default=0.15, help='the ratio of stop ret')
parser.add_argument('--hold_num', type=int,  default=5, help='the ratio of stop ret')
parser.add_argument('--open_thred', type=float,  default=0.4, help='the ratio of stop ret')
parser.add_argument('--close_thred', type=float,  default=0.6, help='the ratio of stop ret')
parser.add_argument('--stop_command', type=bool,  default=True, help='the ratio of stop ret')
parser.add_argument('--sub_command', type=bool,  default=False, help='the ratio of stop ret')

args = parser.parse_args()
from feature_eng.feature_display import Feature_display, IC_display, Cor_display_fast, Cor_display_straitfy
import json
def feature_fliter(root_lst, thred = 0.8, method='spearman'):#pearson
    ic_dis = IC_display(start_date='2020-01-01', end_date='2023-02-05',feature_root=root_lst, method=method)
    ic_dis.info_generate()
    del ic_dis
    cor_dis = Cor_display_fast(start_date='2020-01-01',end_date='2023-02-05',thred=thred,nan_thred=0.03,cor_thred=0.01, feature_root=root_lst, method=method)
    cor_dis.cor_generate()
    del cor_dis

args = parser.parse_args()
lst = [ 'ind', 'ind9', '101','191'] 
args.feature_root = [os.path.join(r'data/cmodty/my_feature', f'feature_data_{i}') for i in lst] 
Get_feature_data_select.select_file = r'data\cmodty\check\fliter_indind9101191.json'
args.label_root = r'data/stock_data/daily/consentrate_price'
args.result_root = r'result/frame/reg/lgb_indind9101191'

# for j,i in enumerate(args.feature_root):
#     r = [i,]
#     tt = 0.8
#     # tt = np.power(0.8, j+1)
#     # print(tt)
#     feature_fliter(r,tt)
# cor_dis = Cor_display_straitfy(start_date='2020-01-01', end_date='2023-02-05',thred=0.8,nan_thred=0.03,cor_thred=0.01, feature_root=args.feature_root, method='spearman')
# cor_dis.cor_generate()

lst_fea = []
for i in args.feature_root:
    lst_temp = sorted(os.listdir(i))
    lst_fea.extend(lst_temp)
args.feature_list = lst_fea


args.model_name = 'lightgbm'
args.result_root = os.path.join(args.result_root, str(args.label_range) ) #f'label_{args.label_range}'
if not os.path.exists(args.result_root):
    os.makedirs(args.result_root)


qb = Quant(args)

class Ml_quant():   
    
    def __init__(self, QuantBuider) -> None:
        self.qb = QuantBuider
        
    def creat_quant(self):
        feature, label, codes, times = self.qb.get_data(Get_feature_data_select, Get_label_data)
        self.qb.rolling_train(codes,times,feature,label)
        # return codes      

from backtest.pos_make.pos_reg.pos_make_limitf2f_sample_stop import Pos_make_rank_thred_month, Pos_make_series_thred_month
from backtest.ret_calc import Ret_calc

def pos_main(args, pos_make_class = Pos_make_rank_thred_month):
    P = pos_make_class(args)
    P.pos_make()
    R = Ret_calc(args, P.buy_pos, P.sell_pos, P.hold_pos,  P.money_df, P.__class__.__name__)
    R.calc_ret()
    del P
    del R

        
M = Ml_quant(qb)
M.creat_quant() 

hold_lst = [5,10,30]
for i in hold_lst:
    args.hold_num = i
    pos_main(args)
    pos_main(args, Pos_make_series_thred_month)


argsdict = vars(args)
with open(os.path.join(args.result_root, 'args.txt'), 'w') as f:
    f.write('{')#这样子字典没有自动的大括号要自己加
    for key in argsdict:
        f.write('\n')
        f.writelines(f'"{str(key)}": {str(argsdict[key])}')
    f.write('\n'+'}')

     
